package mrs.util;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;


/**
 * User: inf_mauror
 */
public class CifradorDES implements Cifrador
{
    private String algoritmo = "DESede";
    private Key llave = null;
    private Cipher cifrador = null;    

    public CifradorDES() throws Exception
    {        
        cifrador = Cipher.getInstance(algoritmo);        
    }


    /**
     * Crea un archivo con un llave simetrica que se
     * aplica para el algoritmo especificado en el
     * parametro.
     *
     * @param algoritmo
     * @param archivo
     * @throws Exception
     */
    public void generarLLave() throws Exception
    {
        llave = KeyGenerator.getInstance(algoritmo).generateKey();        
    }

    /**
     * Crea un objeto llave (SecretKey) a partir
     * de un archivo.
     *
     * @param archivoLLave
     * @throws Exception
     */
    public void abrirLlave(InputStream is) throws IOException
    {        
        int n = is.available();
        byte data[] = new byte[n];

        for(int i=0; i < n; i++)
        {
            data[i] = (byte)is.read();
        }
        llave = new SecretKeySpec(data, algoritmo);        
    }
    
    public void guardarLlave(OutputStream os) throws IOException
    {
    	byte[] data = llave.getEncoded();        
        os.write(data);
        os.flush();        
    }

    public byte[] encriptar(byte[] dataInput) throws Exception
    {
        byte dataOutput[];

        cifrador.init(Cipher.ENCRYPT_MODE, llave);
        dataOutput = cifrador.doFinal(dataInput);

        /*
        for(int i=0; i < dataOutput.length; i++)
        {
            System.out.print(dataOutput[i]);
        }
        */
        return dataOutput;
    }
    
    public byte[] encriptar(byte data[], OutputStream os) throws Exception
    {
    	byte[] dataOutput = encriptar(data);
    	os.write(dataOutput);
    	
		return dataOutput;    	
    }   

    public byte[] desencriptar(byte[] dataInput) throws Exception
    {
        byte dataOutput[];

        cifrador.init(Cipher.DECRYPT_MODE, llave);
        dataOutput = cifrador.doFinal(dataInput);
        return dataOutput;
    }
    
    public byte[] desencriptar(InputStream is) throws Exception
    {
    	byte dataOutput[];    	
    	int n = is.available();    	
        byte dataInput[] = new byte[n];

        for(int i=0; i < n; i++)
        {
            dataInput[i] = (byte)is.read();
        }  
        dataOutput = desencriptar(dataInput);
        return dataOutput;   	
    }

    public void encriptarEnArchivo(String datos, String archivo)throws Exception
    {        
        FileOutputStream out = new FileOutputStream(archivo);
        encriptar(datos.getBytes(),out);
        out.close();
    }

    public String desencriptarDesdeArchivo(String archivo)throws Exception
    {
        FileInputStream in = new FileInputStream(archivo);


        int n = in.available();
        byte dataInput[] = new byte[n];

        for(int i=0; i < n; i++)
        {
            dataInput[i] = (byte)in.read();
        }
        in.close();
        byte dataOutput[] = desencriptar(dataInput);
        return new String(dataOutput);
    }
}
